import { ApiProperty, getSchemaPath } from '@nestjs/swagger';
import { CrudValidationGroups } from '@nestjsx/crud';
import { hashSync } from 'bcryptjs';
import { IsBoolean, IsNumber, IsOptional, IsString, ValidateNested } from 'class-validator';
import {
  BeforeInsert,
  BeforeUpdate, Column,
  Entity,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn
} from 'typeorm';
import { BaseEntity } from './base.entity';
import { NationEnum } from './enum/nation.enum';
import { SexEnum } from './enum/sex.enum';
import { Feedback } from './feedback.entity';
import { Group } from './group.entity';
import { Logger } from './logger.entity';
import { Village } from './village.entity';

const { CREATE, UPDATE } = CrudValidationGroups;

@Entity()
export class Villager extends BaseEntity {
  @ApiProperty({
    description: '村民 -主键',
    required: false,
  })
  @PrimaryGeneratedColumn()
  id?: number;

  @ApiProperty({
    example: 1,
    description: '所属村',
    required: true,
    oneOf: [
      {
        type: 'Number',
      },
      {
        $ref: getSchemaPath(() => Village),
      },
    ],
  })
  @IsNumber({}, { always: true })
  @ManyToOne(
    () => Village,
    Village => Village.villager,
    {
      cascade: true,
    },
  )
  village: Number | Village;

  @ApiProperty({
    example: 1,
    description: '所属组',
    required: true,
    oneOf: [
      {
        type: 'Number',
      },
      {
        $ref: getSchemaPath(() => Group),
      },
    ],
  })
  @IsNumber({}, { always: true })
  @IsOptional({ always: true })
  @ManyToOne(
    () => Group,
    Group => Group.villager,
    {
      cascade: true,
    },
  )
  group: Number | Group;

  @ApiProperty({
    example: '名字',
    description: '名字',
    required: true,
  })
  @IsString({ always: true })
  @Column({
    type: "char",
    length: 255,
  })
  name: string;

  @ApiProperty({
    example: SexEnum.men,
    description: '性别',
    required: true,
    enum: SexEnum
  })
  @IsNumber({}, { always: true })
  @Column({
    type: "enum",
    enum: SexEnum,
  })
  sex: SexEnum;

  @ApiProperty({
    example: NationEnum.HAN,
    description: '民族',
    required: false,
    enum: NationEnum
  })
  @IsNumber({}, { always: true })
  @IsOptional({ always: true })
  @Column({
    nullable: true,
    type: "enum",
    enum: NationEnum,
  })
  nation: NationEnum;

  @ApiProperty({  
    example: 176666666666,
    description: '电话',
    required: false,
  })
  @IsString()
  @IsOptional()
  @Column({
    nullable: true
  })
  phone: string;

  @ApiProperty({
    example: 5555555555,
    description: '身份证号',
    required: false,
  })
  @IsString({ always: true })
  @IsOptional({ always: true })
  @Column({
    type: "char",
    length: 255,
    nullable: true
  })
  identityNumber: string;

  @ApiProperty({
    example: '地址',
    description: '地址',
    required: false,
  })
  @IsString({ always: true })
  @IsOptional({ always: true })
  @Column({
    type: "char",
    length: 255,
    nullable: true
  })
  address: string;

  @ApiProperty({
    example: 1111,
    description: '账号',
    required: true,
  })
  @IsString({ always: true })
  @Column({
    type: "char",
    length: 255,
  })
  account: string;

  @ApiProperty({
    example: '用户密码',
    description: '用户密码',
    required: true
  })
  @IsString({ always: true })
  @IsOptional({ always: true })
  @Column({
    select: false,
    // nullable: true,
  })
  password: string

  @ApiProperty({
    example: 1,
    description: '发起的 反馈',
    required: false,
    type: Number,
  })
  @ValidateNested({ always: true })
  @OneToMany(
    type => Feedback,
    Feedback => Feedback.villager,
  )
  feedback?: Feedback[];

  @ApiProperty({
    example: false,
    description: '是否密码加密 -> 是否初始化',
    required: false
  })
  @IsBoolean()
  @IsOptional()
  @Column({
    default: false
  })
  init: Boolean

  @OneToMany(() => Logger, Logger => Logger.villager)
  logs: Logger []

  @BeforeInsert()
  insertDates() {
    // console.log(this.password)
    if(!this.password) {
      this.password = hashSync('123456')
    } else {
      this.password = hashSync(this.password)
    }
  }

  @BeforeUpdate()
  updateDates() {
    // console.log(this.password)
    if(!this.password) {
      // this.password = null
    } else {
      this.password = hashSync(this.password)
    }
  }
}
